package xjay.ai.emotionalsupport.agent;

import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.vectorstore.QuestionAnswerAdvisor;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.tool.ToolCallback;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Flux;
import xjay.ai.emotionalsupport.chatmemory.ChatHistoryService;
import xjay.ai.emotionalsupport.rag.RagService;

import java.io.IOException;
import java.util.List;


@Component
public class DivinationAgent extends CharacterBaseAgent{
    private final ChatHistoryService chatHistoryService;

//    @Resource
//    private PdfRagService ragService; //是pdf的检索


    String FINAL_PROMPT;

    public DivinationAgent(
            @Qualifier("agentTools") ToolCallback[] agentTools,
            ChatModel qwenChatModel,
            @Qualifier("divinationRag") RagService ragService,
            ChatHistoryService chatHistoryService) throws IOException {
        super(agentTools); //在CharacterBaseAgent类

        super.setAgentName("DivinationAgent"); //BaseAgent
        String SYSTEM_PROMPT = """
                你是专业的占卜师"星语"，具备深厚的占星学知识和敏锐的洞察力。
                
                核心能力：
                1. 准确理解用户的占卜需求（星座运势、感情、事业、健康等）
                2. 系统性地收集和分析相关信息
                3. 基于占星学原理进行逻辑推理
                4. 提供有价值的建议和指导
                
                工作原则：
                - 思考过程要严谨、逻辑清晰
                - 充分利用搜索工具获取最新信息
                - 结合占星学知识进行深度分析
                - 确保建议具有实用性和指导意义
                - 不要有任何这种💫、✨、📚符号出现
                """;
        String INSTRUCTION_PROMPT = """
                请严格按照以下ReAct框架进行占卜分析：
                
                1. Thought: 深度分析用户问题
                   - 识别用户的具体需求（星座、时间范围、关注领域）
                   - 确定需要搜索的关键信息，确定工具调用类型
                   - 制定分析策略
                
                2. Action: 使用工具获取信息，如果模型认为不用再调用其他什么工具了，就调用taskTerminate工具结束分析
                   - 搜索相关星座运势、占星学资讯
                   - 获取最新的占星学观点和预测
                
                3. Observation: 系统分析搜索结果
                   - 提取关键信息和数据
                   - 识别可靠的占星学观点
                   - 整理分析要点
                
                要求：
                - 每个步骤的思考要详细、逻辑清晰
                - 充分利用搜索到的信息
                - 分析过程要专业、严谨
                - 确保建议的实用性和准确性
                """;

        FINAL_PROMPT = """
                你是温暖的占卜师朋友"星语"，现在需要将内部的专业分析结果转换为微信聊天风格的回复。
                重复：以微信聊天的形式和语气和风格进行回复。
                
                输入内容：持久化的历史对话上下文和程序内部的占卜分析过程和结果（包含Thought、Action、Observation等元信息）全部上下文
                
                输出要求：
                1. 字数控制在100-150字，除非是比较重要的谈话，可以超出字数限制
                2. 语气轻松亲切，像朋友聊天
                3. 多用"你"而不是"您"
                4. 绝对不要使用任何emoji表情符号或特殊符号
                5. 不使用Markdown格式
                6. 语言口语化，有温度
                7. 结尾加上互动性的反问或关怀
                8. 保持纯文字回复，不出现任何符号
                
                转换原则：
                - 提取核心的占卜结果和建议
                - 忽略技术性的分析过程
                - 用朋友的语气重新表达
                - 增加情感关怀和互动元素
                - 让回复像是在微信上和好朋友聊天
                
                示例风格：
                "哈哈你这个天秤座真的很典诶～这周感觉你运气挺不错的，可能会遇到一些有意思的人或者事情。不过你知道的，天秤座有时候会纠结，遇到选择的时候记得相信自己的直觉哦！怎么说，最近是不是有什么让你特别在意的事情呀？"
                """;



        super.setSystemPrompt(SYSTEM_PROMPT);
        super.setInstructionPrompt(INSTRUCTION_PROMPT);
        super.setMaxStep(5);

        //设置历史对话服务
        super.setChatHistoryService(chatHistoryService);

        //STEP:设置rag
        super.setRagService(ragService);
        super.getRagService().loadMarkdown();
        //STEP:设置模型
        ChatClient agentChatClient = ChatClient.builder(qwenChatModel)
                .defaultAdvisors(new QuestionAnswerAdvisor(ragService.rag()))// IMPORTANT: 模型包含rag功能,在这里体现
                .build();
        super.setChatClient(agentChatClient);
        this.chatHistoryService = chatHistoryService;
    }

    /**
     * note: 冷启动
     * @param userId
     * @param sessionId
     */
    public void warmUp(String userId, String sessionId) {


        List<Message> historyMessages= super.getChatHistoryService().contextMessages(userId, sessionId);
        if(!historyMessages.isEmpty()){
            super.setDialogOnlyList(historyMessages);
            super.getMessageList().addAll(historyMessages); //拿回来历史会话
        }

    }

    /**
     *
     * @param userMessage
     * @param userId
     * @param sessionId
     * @return
     */
    public String divinationChat(String userMessage, String userId, String sessionId) {


        String results = super.run(userMessage);


        Prompt prompt = new Prompt(getMessageList(), this.getChatOptions());


        // STEP:使用FINAL_PROMPT,将内部分析结果转换为微信聊天风格的回复
        String assistantReply = getChatClient().prompt(prompt)
                .system(FINAL_PROMPT)
                .user(userMessage)
                .call()
                .content();

        //STEP:数据库持久化，插入一问一答
        chatHistoryService.insertQA(userId, sessionId, userMessage, assistantReply);
        return assistantReply;
    }

    public Flux<String> divinationChatWithSSE(String userMessage) {

        String results = super.run(userMessage); //results是一系列过程，run的时候，已经集成到List<Message>了

        // 从消息列表中提取最后一个助手回复作为占卜分析结果
        Prompt prompt = new Prompt(getMessageList(), this.getChatOptions());


        // 使用FINAL_PROMPT将内部分析结果转换为微信聊天风格的回复
        return getChatClient().prompt(prompt)
                .system(FINAL_PROMPT)
                .user(userMessage)
                .stream()
                .content();
    }

    //rag文档删除
    public void deleteDocument(String filename) {
        // 按文件名删除
        getRagService().deleteDocument(filename); //metadata就是一个Map
    }

    // 删除多个文档ID
    public void deleteDocuments(List<String> documentIds) {
        getRagService().deleteDocuments(documentIds);
    }
}
